package com.tsing.basic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tsing.basic.entity.Permission;
import com.tsing.basic.entity.Role;
import com.tsing.basic.mapper.PermissionMapper;
import com.tsing.basic.mapper.RoleMapper;
import com.tsing.basic.service.IRoleService;
import com.tsing.basic.vo.dto.PermissionTreeChildrenDTO;
import com.tsing.basic.vo.req.*;
import com.tsing.basic.vo.resp.PermissionRespVo;
import com.tsing.basic.vo.resp.PermissionTreeRespVo;
import com.tsing.basic.vo.resp.RoleRespVo;
import com.tsing.common.exceptions.BusinessException;
import com.tsing.common.exceptions.ServerException;
import com.tsing.common.service.UserRedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author TheTsing
 * @since 2021-03-29
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private UserRedisService userRedisService;

    @Resource
    private PermissionMapper permissionMapper;

    @Override
    public void addRole(RoleAddReqVo reqVo) {
        if (0 != baseMapper.selectCount(new QueryWrapper<Role>().eq("name", reqVo.getName()))) {
            throw new BusinessException(ServerException.Proxy.ROLENAME_IS_NOTNULL);
        }
        Role role = new Role();
        BeanUtils.copyProperties(reqVo, role);
        role.setDescription(reqVo.getRemark());
        baseMapper.insert(role);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void deleteRole(IdsReqVo reqVo) {
        if (!StringUtils.isBlank(baseMapper.haveRelevance(reqVo.getIds()))) {
            throw new BusinessException(ServerException.Proxy.ROLE_HAVE_RELEVANCE);
        }
        baseMapper.deleteBatchIds(reqVo.getIds());
        baseMapper.deleteRelevance(reqVo.getIds());
    }

    @Override
    public RoleRespVo getRoleById(IdReqVo reqVo) {
        Role role = baseMapper.selectById(reqVo.getId());
        RoleRespVo roleRespVo = new RoleRespVo();
        BeanUtils.copyProperties(role, roleRespVo);
        roleRespVo.setRemark(role.getDescription());
        return roleRespVo;
    }

    @Override
    public void updateRole(RoleUpdateReqVo reqVo) {
        if (0 != baseMapper.selectCount(new QueryWrapper<Role>().eq("name", reqVo.getName())
                .ne("id", reqVo.getId()))) {
            throw new BusinessException(ServerException.Proxy.ROLENAME_IS_NOTNULL);
        }
        Role role = new Role();
        BeanUtils.copyProperties(reqVo, role);
        role.setDescription(reqVo.getRemark());
        baseMapper.updateById(role);
    }

    @Override
    public Page<RoleRespVo> rolePage(RolePageReqVo reqVo) {
        Page<Role> page = new Page<>(reqVo.getPageNum(), reqVo.getPageSize());
        List<RoleRespVo> list = baseMapper.rolePage(reqVo, page);
        Page<RoleRespVo> rolePage = new Page<>();
        rolePage.setTotal(page.getTotal());//总条数
        rolePage.setCurrent(page.getCurrent());//页码
        rolePage.setSize(page.getSize());//当前页个数
        rolePage.setRecords(list);//当前页数据
        return rolePage;
    }

    @Override
    public List<PermissionRespVo> getPermissionByRoleId(IdReqVo reqVo) {
        return baseMapper.getPermissionByRoleId(reqVo.getId());
    }

    @Override
    public List<PermissionTreeRespVo> getPermissionTree() {
        Map<String, List<Permission>> collect = permissionMapper.selectList(null).stream()
                .collect(Collectors.groupingBy(item -> item.getUrl().split("/")[1]));
        ArrayList<PermissionTreeRespVo> permissionTreeRespVos = new ArrayList<>();
        for (Map.Entry<String, List<Permission>> entry : collect.entrySet()) {
            PermissionTreeRespVo permissionTreeRespVo = new PermissionTreeRespVo();
            permissionTreeRespVo.setLabel(entry.getKey());
            ArrayList<PermissionTreeChildrenDTO> permissionTreeChildrenDTOS = new ArrayList<>();
            for (Permission permission : entry.getValue()) {
                PermissionTreeChildrenDTO permissionTreeChildrenDTO = new PermissionTreeChildrenDTO();
                permissionTreeChildrenDTO.setId(permission.getId());
                permissionTreeChildrenDTO.setLabel(permission.getDescription());
                permissionTreeChildrenDTOS.add(permissionTreeChildrenDTO);
            }
            permissionTreeRespVo.setChildren(permissionTreeChildrenDTOS);
            permissionTreeRespVos.add(permissionTreeRespVo);
        }
        return permissionTreeRespVos;
    }

    @Override
    public void bindPermission(BindPermissionReqVo reqVo) {
        baseMapper.deletePermission(reqVo.getId());
        if (null != reqVo.getPermissionId() && reqVo.getPermissionId().size() != 0) {
            baseMapper.bindPermission(reqVo);
        }
        userRedisService.savePermission2Redis(permissionMapper.selectAllpermission());
    }

}
